package com.ams.webservice;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONArray;
import com.alipay.api.domain.OrderDetail;
import com.ams.common.entity.DataInsEntity;
import com.ams.common.entity.InsDetailEntity;
import com.ams.common.entity.InsEntity;
import com.ams.common.entity.OrderTaskResult;
import com.ams.common.utils.RedisLock;
import com.ams.common.utils.SnConstant;
import com.ams.enums.*;
import com.ams.model.*;
import com.ams.service.*;
import com.jfinal.plugin.activerecord.Db;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.Predicate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.jws.WebService;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;

/**
 * Created by IntelliJ IDEA.
 * User: andy.qu
 * Date: 2019/5/13
 */
@WebService(
        targetNamespace = "http://CxfService.webservice.service.wms.modules.tbl.com"
)
@Component
@Slf4j
public class Wcs2wdsServiceImpl implements IWcs2wdsService {

    @Autowired
    EntrancePrivilegeService entrancePrivilegeService;

    @Autowired
    DocAsnDetailsService docAsnDetailsService;

    @Autowired
    DocAsnHeaderService docAsnHeaderService;

    @Autowired
    DocOrderHeaderService docOrderHeaderService;

    @Autowired
    DocOrderDetailsService docOrderDetailsService;
;

    @Autowired
    InvLotLocIdService invLotLocIdService;

    @Autowired
    RedisLock redisLock;

    @Autowired
    SnService snService;

    private final Long TIME_OUT = 10000L;
    final String RACK_ID = "1";

    public Wcs2wdsServiceImpl() {
        log.info("'Wcs2wdsServiceImpl' >>>>>>>>>>>>>>");
    }

    @Override
    public String SendWms1TaskJson(String para) {
        DataInsEntity dataInsEntity = JSONArray.parseObject(para, DataInsEntity.class);
        List<InsEntity> insEntities = dataInsEntity.getData();
        log.info("Wcs2wdsServiceImpl SendWms1TaskJson------------ {}", insEntities);
        //创建入库出库表单

        List<OrderTaskResult> orderTaskResultList = new ArrayList<>();
        for (InsEntity insEntity : insEntities) {
            if (insEntity.getOperateType().equals(OrderTaskTypeEnum.STOCK_IN.getMessage())) {
                String asnCode = snService.generateDocAsn();
                // 入库操作
                DocAsnHeader docAsnHeader = new DocAsnHeader();
                docAsnHeader.setAsnno(asnCode);
                docAsnHeader.setAsnreference1(insEntity.getTaskno());
                docAsnHeader.setAsnstatus(OrderStatusEnum.CREATE.getMessage());
                docAsnHeader.setAddwho(insEntity.getRfidCode());
                docAsnHeader.setWarehouseid(insEntity.getWhno());
                docAsnHeader.setHEdi01(insEntity.getStoArea());
                docAsnHeader.setHEdi02(insEntity.getBinnoFrom());
                docAsnHeader.setHEdi03(insEntity.getBinnoTo());
                docAsnHeader.setHEdi04(insEntity.getTaskSource());
                docAsnHeader.setHEdi05(insEntity.getPalletLoc());
                DateTime taskTime = DateUtil.parse(insEntity.getTaskTime(), "yyyy-MM-dd HH:mm:ss");
                docAsnHeader.setPriority(insEntity.getTaskLevel() + "");
                docAsnHeader.setCreateTime(new Date());
                docAsnHeader.setUpdateTime(new Date());
                docAsnHeader.setCustomerid("WRC");
                docAsnHeader.setAsncreationtime(taskTime);
                List<InsDetailEntity> insDetailEntityList = insEntity.getReserve();
                List<DocAsnDetails> docAsnDetailsList = new ArrayList<>();
                boolean detailSucc = true;
                for (InsDetailEntity insDetailEntity : insDetailEntityList) {
                    String asnDetailCode = snService.generateDocAsnDetail();
                    DocAsnDetails docAsnDetails = new DocAsnDetails();
                    docAsnDetails.setAsnno(asnCode);
                    docAsnDetails.setAsnlineno(asnDetailCode);
                    docAsnDetails.setAddwho(insEntity.getRfidCode());
                    docAsnDetails.setSku(insDetailEntity.getMatno());
                    docAsnDetails.setAlternativesku(insDetailEntity.getMatText());
                    docAsnDetails.setUom(insDetailEntity.getUnit());
                    docAsnDetails.setLotatt04(insDetailEntity.getBatch());
                    docAsnDetails.setExpectedqty(BigDecimal.valueOf(insDetailEntity.getQuantity()));
                    docAsnDetails.setReceivedqty(BigDecimal.ZERO);
                    docAsnDetails.setCustomerid("WRC");
                    docAsnDetails.setCreateTime(new Date());
                    docAsnDetails.setUpdateTime(new Date());

                    boolean exsits = CollectionUtils.exists(docAsnDetailsList, new Predicate() {
                        @Override
                        public boolean evaluate(Object o) {
                            DocAsnDetails _docAsnDetails = (DocAsnDetails) o;
                            return _docAsnDetails.getAlternativedescrC().equals(docAsnDetails.getAlternativedescrC());
                        }
                    });

                    if(exsits) {
                        OrderTaskResult orderTaskResult = OrderTaskResult.error(ResultEnum.MAT_DETAIL_REPETITION.getCode() + "", ResultEnum.MAT_DETAIL_REPETITION.getMessage(), insEntity.getTaskno(), insEntity.getTaskSource(), insEntity.getWhno());
                        orderTaskResultList.add(orderTaskResult);
                        detailSucc = false;
                        break;
                    } else {
                        docAsnDetailsList.add(docAsnDetails);
                    }
                }

                if (!detailSucc) {
                    continue;
                }


                // 加入到门禁权限表中
                EntrancePrivilege entrancePrivilege = new EntrancePrivilege();
                entrancePrivilege.setUserid(insEntity.getRfidCode());
                entrancePrivilege.setEntrancestatus(EntranceStatus.ACCESS.getMessage());
                List<EntrancePrivilege> entrancePrivilegeList = entrancePrivilegeService.findByModel(entrancePrivilege);
                if (entrancePrivilegeList.size() > 0) {
                    OrderTaskResult orderTaskResult = OrderTaskResult.error(ResultEnum.API_ENTRANCE_USER_ACCESS_EXISTS.getCode() + "", ResultEnum.API_ENTRANCE_USER_ACCESS_EXISTS.getMessage(), insEntity.getTaskno(), insEntity.getTaskSource(), insEntity.getWhno());
                    orderTaskResultList.add(orderTaskResult);
                    continue;
                }

                Db.batchSave(docAsnDetailsList, 20);
                docAsnHeaderService.insert(docAsnHeader);


                entrancePrivilege.setCreatetime(new Date());
                entrancePrivilege.setUpdatetime(new Date());
                entrancePrivilege.setOrderno(asnCode);
                entrancePrivilegeService.insert(entrancePrivilege);

                //返回参数
                OrderTaskResult orderTaskResult = OrderTaskResult.success(insEntity.getTaskno(), insEntity.getTaskSource(), insEntity.getWhno());
                orderTaskResultList.add(orderTaskResult);
            } else if (insEntity.getOperateType().equals(OrderTaskTypeEnum.STOCK_OUT.getMessage())) {
                //todo 需要加锁
                String orderCode = snService.generateDocOrder();
                // 出库操作
                DocOrderHeader docOrderHeader = new DocOrderHeader();
                docOrderHeader.setOrderno(orderCode);
                docOrderHeader.setSoreference1(insEntity.getTaskno());
                docOrderHeader.setSostatus(OrderStatusEnum.CREATE.getMessage());
                docOrderHeader.setAddwho(insEntity.getRfidCode());
                docOrderHeader.setWarehouseid(insEntity.getWhno());
                docOrderHeader.setHEdi01(insEntity.getStoArea());
                docOrderHeader.setHEdi02(insEntity.getBinnoFrom());
                docOrderHeader.setHEdi03(insEntity.getBinnoTo());
                docOrderHeader.setHEdi04(insEntity.getTaskSource());
                docOrderHeader.setHEdi05(insEntity.getPalletLoc());
                docOrderHeader.setCustomerid("WRC");
                DateTime taskTime = DateUtil.parse(insEntity.getTaskTime(), "yyyy-MM-dd HH:mm:ss");
                docOrderHeader.setPriority(insEntity.getTaskLevel() + "");
                docOrderHeader.setCreateTime(new Date());
                docOrderHeader.setUpdateTime(new Date());
                docOrderHeader.setOrdertime(taskTime);
                List<InsDetailEntity> insDetailEntityList = insEntity.getReserve();
                boolean detailSucc = true;
                List<DocOrderDetails> docOrderDetailsList = new ArrayList<>();
                for (InsDetailEntity insDetailEntity : insDetailEntityList) {
                    //TODO 需要加同步锁防止并发的时候多消耗库存
                    //检查当前出库物料库存是否够
                    InvLotLocId invLotLocId = new InvLotLocId();
                    invLotLocId.setRackid(RACK_ID);
                    invLotLocId.setLocationid(docOrderHeader.getHEdi01());
                    InvLotLocId dbInvLotLocId = invLotLocIdService.findFirstByModel(invLotLocId);
//                    invLotLocId.setCustomerid("WRC");
//                    invLotLocId.setLotnum(insDetailEntity.getBatch());
//                    invLotLocId.setSku(insDetailEntity.getMatno());


                    if (dbInvLotLocId != null) {
                        BigDecimal availableQty = dbInvLotLocId.getQty().subtract(dbInvLotLocId.getQtyallocated());
                        if (availableQty.compareTo(BigDecimal.valueOf(insDetailEntity.getQuantity())) < 0) {
                            OrderTaskResult orderTaskResult = OrderTaskResult.error(ResultEnum.STOCK_OUT_ENOUGH.getCode() + "", ResultEnum.STOCK_OUT_ENOUGH.getMessage(), insEntity.getTaskno(), insEntity.getTaskSource(), insEntity.getWhno());
                            orderTaskResultList.add(orderTaskResult);
                            detailSucc = false;
                            break;
//                            throw new RRException(String.format("Customerid = %s Lotnum = %s Sku = %s Locationid = %s 库存不够 availableQty = %s", invLotLocId.getCustomerid(), invLotLocId.getLotnum(), invLotLocId.getSku(), invLotLocId.getLocationid(), availableQty.toString()), ResultEnum.STOCK_OUT_ENOUGH.getCode());
                        }
                    }else if(dbInvLotLocId == null) {
                        OrderTaskResult orderTaskResult = OrderTaskResult.error(ResultEnum.STOCK_OUT_ENOUGH.getCode() + "", ResultEnum.STOCK_OUT_ENOUGH.getMessage(), insEntity.getTaskno(), insEntity.getTaskSource(), insEntity.getWhno());
                        orderTaskResultList.add(orderTaskResult);
                        detailSucc = false;
                        break;
//                        throw new RRException(String.format("Customerid = %s Lotnum = %s Sku = %s Locationid = %s 库存不够 availableQty = %s", invLotLocId.getCustomerid(), invLotLocId.getLotnum(), invLotLocId.getSku(), invLotLocId.getLocationid(), "0"), ResultEnum.STOCK_OUT_ENOUGH.getCode());
                    }

                    if(!detailSucc) {
                        break;
                    }

                    //出库物料操作
                    String orderDetailCode = snService.generateDocOrderDetail();
                    DocOrderDetails docOrderDetails = new DocOrderDetails();
                    docOrderDetails.setOrderno(orderCode);
                    docOrderDetails.setOrderlineno(orderDetailCode);
                    docOrderDetails.setAddwho(insEntity.getRfidCode());
                    docOrderDetails.setSku(insDetailEntity.getMatno());
                    docOrderDetails.setUom(insDetailEntity.getUnit());
                    docOrderDetails.setLotatt04(insDetailEntity.getBatch());
                    docOrderDetails.setAlternativesku(insDetailEntity.getMatText());
                    docOrderDetails.setQtyordered(BigDecimal.valueOf(insDetailEntity.getQuantity()));
                    docOrderDetails.setQtyshipped(BigDecimal.ZERO);
                    docOrderDetails.setCustomerid("WRC");
                    docOrderDetails.setCreateTime(new Date());
                    docOrderDetails.setUpdateTime(new Date());

                    boolean exsits = CollectionUtils.exists(docOrderDetailsList, new Predicate() {
                        @Override
                        public boolean evaluate(Object o) {
                            DocOrderDetails _orderDetails = (DocOrderDetails) o;
                            return _orderDetails.getSku().equals(docOrderDetails.getSku());
                        }
                    });

                    if(exsits) {
                        OrderTaskResult orderTaskResult = OrderTaskResult.error(ResultEnum.MAT_DETAIL_REPETITION.getCode() + "", ResultEnum.MAT_DETAIL_REPETITION.getMessage(), insEntity.getTaskno(), insEntity.getTaskSource(), insEntity.getWhno());
                        orderTaskResultList.add(orderTaskResult);
                        detailSucc = false;
                        break;
                    } else {
                        docOrderDetailsList.add(docOrderDetails);
                    }

                }

                if(!detailSucc) {
                    continue;
                }

                // 加入到门禁权限表中
                EntrancePrivilege entrancePrivilege = new EntrancePrivilege();
                entrancePrivilege.setUserid(insEntity.getRfidCode());
                entrancePrivilege.setEntrancestatus(EntranceStatus.ACCESS.getMessage());

                List<EntrancePrivilege> entrancePrivilegeList = entrancePrivilegeService.findByModel(entrancePrivilege);
                if (entrancePrivilegeList.size() > 0) {
                    OrderTaskResult orderTaskResult = OrderTaskResult.error(ResultEnum.API_ENTRANCE_USER_ACCESS_EXISTS.getCode() + "", ResultEnum.API_ENTRANCE_USER_ACCESS_EXISTS.getMessage(), insEntity.getTaskno(), insEntity.getTaskSource(), insEntity.getWhno());
                    orderTaskResultList.add(orderTaskResult);
                    continue;
                }

                Db.batchSave(docOrderDetailsList, 20);

                for (DocOrderDetails orderDetails : docOrderDetailsList) {
                    //更新可分配库存
                    InvLotLocId invLotLocId = new InvLotLocId();
                    invLotLocId.setRackid(RACK_ID);
                    invLotLocId.setLocationid(docOrderHeader.getHEdi01());
                    InvLotLocId dbInvLotLocId = invLotLocIdService.findFirstByModel(invLotLocId);
                    dbInvLotLocId.setQtyallocated(dbInvLotLocId.getQtyallocated().add(orderDetails.getQtyordered()));
                    invLotLocIdService.update(dbInvLotLocId);
                }
                docOrderHeaderService.insert(docOrderHeader);

                entrancePrivilege.setCreatetime(new Date());
                entrancePrivilege.setUpdatetime(new Date());
                entrancePrivilege.setOrderno(orderCode);
                entrancePrivilegeService.insert(entrancePrivilege);

                //返回参数
                OrderTaskResult orderTaskResult = OrderTaskResult.success(insEntity.getTaskno(), insEntity.getTaskSource(), insEntity.getWhno());
                orderTaskResultList.add(orderTaskResult);

            } else {
                OrderTaskResult orderTaskResult = OrderTaskResult.error(ResultEnum.OPERATE_NOT_EXISTS.getCode() + "", ResultEnum.OPERATE_NOT_EXISTS.getMessage(), insEntity.getTaskno(), insEntity.getTaskSource(), insEntity.getWhno());
                orderTaskResultList.add(orderTaskResult);
//                throw new RRException(ResultEnum.OPERATE_NOT_EXISTS);
            }
        }

        return JSONArray.toJSONString(orderTaskResultList);
    }

    @Override
    public String CancelWms1TaskJson(String data) {
        DataInsEntity dataInsEntity = JSONArray.parseObject(data, DataInsEntity.class);
        List<InsEntity> insEntities = dataInsEntity.getData();
        List<OrderTaskResult> orderTaskResultList = new ArrayList<>();
        for (InsEntity insEntity : insEntities) {
            DocAsnHeader asnQuery = new DocAsnHeader();
            asnQuery.setAsnstatus(OrderStatusEnum.CREATE.getMessage());
            asnQuery.setAsnreference1(insEntity.getTaskno());
            DocAsnHeader docAsnHeader =  docAsnHeaderService.findFirstByModel(asnQuery);
            if (docAsnHeader == null) {
                DocOrderHeader orderQuery = new DocOrderHeader();
                orderQuery.setSostatus(OrderStatusEnum.CREATE.getMessage());
                orderQuery.setSoreference1(insEntity.getTaskno());
                DocOrderHeader docOrderHeader =  docOrderHeaderService.findFirstByModel(orderQuery);
                if (docOrderHeader != null) {
                    //出库单取消
                    docOrderHeader.setSostatus(OrderStatusEnum.CANCEL.getMessage());
                    docOrderHeaderService.update(docOrderHeader);
                    OrderTaskResult orderTaskResult = OrderTaskResult.success(insEntity.getTaskno(), insEntity.getTaskSource(), insEntity.getWhno());
                    orderTaskResultList.add(orderTaskResult);

                    DocOrderDetails docOrderDetails = new DocOrderDetails();
                    docOrderDetails.setOrderno(docOrderHeader.getOrderno());

                    // 需要回退分配库存
                    List<DocOrderDetails> docOrderDetailsList = docOrderDetailsService.findByModel(docOrderDetails);
                    if (docOrderDetailsList != null) {
                        for (DocOrderDetails orderDetails : docOrderDetailsList) {
                            //更新可分配库存
                            InvLotLocId invLotLocId = new InvLotLocId();
                            invLotLocId.setRackid(RACK_ID);
                            invLotLocId.setLocationid(docOrderHeader.getHEdi01());
                            InvLotLocId dbInvLotLocId = invLotLocIdService.findFirstByModel(invLotLocId);
                            dbInvLotLocId.setQtyallocated(dbInvLotLocId.getQtyallocated().subtract(orderDetails.getQtyordered()));
                            invLotLocIdService.update(dbInvLotLocId);
                        }
                    }

                } else {
                    //没找到对应指令编号
                    OrderTaskResult orderTaskResult = OrderTaskResult.error(ResultEnum.WS_TASKNO_NOT_FOUND.getCode() + "", ResultEnum.WS_TASKNO_NOT_FOUND.getMessage() + "",insEntity.getTaskno(), insEntity.getTaskSource(), insEntity.getWhno());
                    orderTaskResultList.add(orderTaskResult);
                }
            } else {
                //入库单取消
                docAsnHeader.setAsnstatus(OrderStatusEnum.CANCEL.getMessage());
                docAsnHeaderService.update(docAsnHeader);
                OrderTaskResult orderTaskResult = OrderTaskResult.success(insEntity.getTaskno(), insEntity.getTaskSource(), insEntity.getWhno());
                orderTaskResultList.add(orderTaskResult);
            }
        }


        entrancePrivilegeService.upadteStatusByStastus(EntranceStatus.ACCESS.getMessage(), EntranceStatus.CANCEL.getMessage());
        return JSONArray.toJSONString(orderTaskResultList);
    }
}